Skip to content

Handle ObjectDisposedException in SignalR OnDisconnectedAsync during shutdown#65457

Draft
adityamandaleeka wants to merge 2 commits intodotnet:mainfrom
adityamandaleeka:signalr_test_ode
Draft

Handle ObjectDisposedException in SignalR OnDisconnectedAsync during shutdown#65457
adityamandaleeka wants to merge 2 commits intodotnet:mainfrom
adityamandaleeka:signalr_test_ode

Conversation

@adityamandaleeka
Copy link
Member

@adityamandaleeka adityamandaleeka commented Feb 18, 2026

Problem

TestServerTests.LongPollingWorks fails intermittently in CI with:

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnDisconnectedAsync(...)

Root Cause

ProcessDeleteAsync in HttpConnectionDispatcher fire-and-forgets server-side connection disposal. When the host shuts down, OnDisconnectedAsync can race with IServiceProvider disposal, causing ObjectDisposedException when creating a DI scope or resolving services.

Fix

Catch ObjectDisposedException at both framework DI boundaries in DefaultHubDispatcher.OnDisconnectedAsync:

  1. Scope creationCreateAsyncScope() fails if the root provider is already disposed
  2. Service resolutionGetRequiredService/hubActivator.Create() can fail if the root provider is disposed after scope creation

In both cases, the host is shutting down and the DI container cannot service requests, so we log at Debug level and no-op gracefully. User hub code exceptions (Hub.OnDisconnectedAsync, middleware) are not caught — only framework DI plumbing is protected.

Since the error is now handled at the source, the LongPollingWorks test does not need an expectedErrorsFilter.

…xception

Long polling DELETE fire-and-forgets server-side connection disposal, so
OnDisconnectedAsync can race with host shutdown and hit a disposed
IServiceProvider. This produces up to two error logs (ErrorDispatchingHubEvent
and FailedDispose) that VerifyNoErrorsScope catches nondeterministically.
Copilot AI review requested due to automatic review settings February 18, 2026 04:22
@github-actions github-actions bot added the area-signalr Includes: SignalR clients and servers label Feb 18, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a flaky test (TestServerTests.LongPollingWorks) that intermittently fails in CI due to a race condition during test teardown. The test uses long polling transport, which fire-and-forgets the server-side connection disposal. When the test host shuts down, the background OnDisconnectedAsync can race with the disposal of the IServiceProvider, resulting in up to two ObjectDisposedException error logs that cause the test to fail nondeterministically. This is not a product bug—it's an expected behavior during shutdown.

Changes:

  • Added expectedErrorsFilter to StartVerifiableLog() to tolerate ObjectDisposedException during test teardown
  • Added System namespace import for ObjectDisposedException
  • Added explanatory comment documenting the race condition

@adityamandaleeka adityamandaleeka marked this pull request as draft February 18, 2026 07:40
@adityamandaleeka
Copy link
Member Author

Marking draft while an updated fix is prepared...

@adityamandaleeka adityamandaleeka changed the title Fix flaky LongPollingWorks test by filtering expected ObjectDisposedException Handle ObjectDisposedException in SignalR OnDisconnectedAsync during shutdown Feb 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-signalr Includes: SignalR clients and servers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants